﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using stockUploader.Core;

namespace stockUploader
{
    public delegate void FinishedDelegate();
    public delegate void InitOverallDelegate(long size);
    public delegate void InitStockDelegate(Stock stock, long size);
    public delegate void InitFileDelegate(FileInfo file, long size);
    public delegate void ProgressChangedDelegate(Stock stock, FileInfo fileInfo, long uploaded, float speed);
    public delegate void FileUploadedDelegate(FileInfo fileInfo, Stock stock);
    public delegate void FileUploadErrorDelegate(FileInfo fileInfo, Stock stock, Exception ex);
    public delegate void StockUploadedDelegate(Stock stock, long filesSize);

    class Worker
    {
        public IEnumerable<FileInfo> Files { get; set; }
        public IEnumerable<Stock> Stocks { get; set; }

        public event InitOverallDelegate InitOverall;
        public event InitStockDelegate InitStock;
        public event InitFileDelegate InitFile;
        public event ProgressChangedDelegate ProgressChanged;
        public event FileUploadedDelegate FileUploaded;
        public event FileUploadErrorDelegate FileUploadError;
        public event StockUploadedDelegate StockUploaded;
        public event FinishedDelegate Finished;

        public void JustDoIt()
        {
            var filesSize = Files.Sum(fi => fi.Length);
            initOverall(Stocks.Count() * filesSize);
            foreach(var stock in Stocks)
            {
                initStock(stock, filesSize);
                FtpStockClient client = new FtpStockClient(stock);
                client.Uploading += new FtpUploadingDelegate(client_Uploading);
                //client.Uploaded += new FtpUploadedDelegate(client_Uploaded);
                foreach(var file in Files)
                {
                    initFile(file, file.Length);
                    try
                    {
                        client.UploadFile(file);
                    }
                    catch(Exception ex)
                    {
                        fileUploadError(file, stock, ex);
                    }
                    fileUploaded(file, stock);
                }
                stockUploaded(stock, filesSize);
            }
            if(Finished != null)
                Finished();
        }

        private void fileUploadError(FileInfo file, Stock stock, Exception ex)
        {
            if(FileUploadError != null) { FileUploadError(file, stock, ex); }
        }

        private void stockUploaded(Stock stock, long filesSize)
        {
            if(StockUploaded != null) { StockUploaded(stock, filesSize); }
        }

        private void fileUploaded(FileInfo file, Stock stock)
        {
            if(FileUploaded != null) { FileUploaded(file, stock); }
        }

        private void initFile(FileInfo file, long size)
        {
            if(InitFile != null) { InitFile(file, size); }
        }

        private void initStock(Stock stock, long size)
        {
            if(InitStock != null) { InitStock(stock, size); }
        }

        private void initOverall(long size)
        {
            if(InitOverall != null) { InitOverall(size); }
        }

        void client_Uploading(object sender, FtpUploading ea)
        {
            if(ProgressChanged != null)
                ProgressChanged(((FtpStockClient)sender).Stock, ea.FileInfo, ea.Uploaded, ea.Speed / 1024);
        }
    }
}
